[IA64] Raise a fault with unimplemented physical address
authorAlex Williamson <alex.williamson@hp.com>
Fri, 14 Mar 2008 21:07:45 +0000 (15:07 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Fri, 14 Mar 2008 21:07:45 +0000 (15:07 -0600)
An unimplemented data fault or an unimplemented instruction trap
should be raised with unimplemented physical address.
Also some cleanups.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
xen/arch/ia64/vmx/vmx_fault.c
xen/arch/ia64/vmx/vmx_virt.c
xen/include/asm-ia64/vmx_vcpu.h

index a9da245728982ba8f11c21395e9ae245b5f887f0..82039fc86b85f15559e77e539c38547f6b76e18a 100644 (file)
@@ -328,6 +328,11 @@ static int vmx_handle_lds(REGS* regs)
     return IA64_FAULT;
 }
 
+static inline int unimpl_phys_addr (u64 paddr)
+{
+    return (pa_clear_uc(paddr) >> MAX_PHYS_ADDR_BITS) != 0;
+}
+
 /* We came here because the H/W VHPT walker failed to find an entry */
 IA64FAULT
 vmx_hpw_miss(u64 vadr, u64 vec, REGS* regs)
@@ -361,12 +366,20 @@ vmx_hpw_miss(u64 vadr, u64 vec, REGS* regs)
             /* DTLB miss.  */
             if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */
                 return vmx_handle_lds(regs);
+            if (unlikely(unimpl_phys_addr(vadr))) {
+                unimpl_daddr(v);
+                return IA64_FAULT;
+            }
             pte = lookup_domain_mpa(v->domain, pa_clear_uc(vadr), NULL);
-            /* Clear UC bit in vadr with the shifts.  */
             if (v->domain != dom0 && (pte & GPFN_IO_MASK)) {
                 emulate_io_inst(v, pa_clear_uc(vadr), 4, pte);
                 return IA64_FAULT;
             }
+        } else {
+            if (unlikely(unimpl_phys_addr(vadr))) {
+                unimpl_iaddr_trap(v, vadr);
+                return IA64_FAULT;
+            }
         }
         physical_tlb_miss(v, vadr, type);
         return IA64_FAULT;
index d9a38d5c8c63521e5cc8344bb4ac8e1bec2313b5..bc119e4f91554a5c12a21adf1ae384c94819a7cc 100644 (file)
@@ -277,9 +277,6 @@ static IA64FAULT vmx_emul_ptc_l(VCPU *vcpu, INST64 inst)
     }
 #ifdef  VMAL_NO_FAULT_CHECK
     if (unimplemented_gva(vcpu,r3) ) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
     }
@@ -338,9 +335,6 @@ static IA64FAULT vmx_emul_ptc_g(VCPU *vcpu, INST64 inst)
     }
 #ifdef  VMAL_NO_FAULT_CHECK
     if (unimplemented_gva(vcpu,r3) ) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
     }
@@ -374,9 +368,6 @@ static IA64FAULT vmx_emul_ptc_ga(VCPU *vcpu, INST64 inst)
     }
 #ifdef  VMAL_NO_FAULT_CHECK
     if (unimplemented_gva(vcpu,r3) ) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
     }
@@ -411,9 +402,6 @@ static IA64FAULT ptr_fault_check(VCPU *vcpu, INST64 inst, u64 *pr2, u64 *pr3)
         return IA64_FAULT;
     }
     if (unimplemented_gva(vcpu,r3) ) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
    }
@@ -635,9 +623,6 @@ static IA64FAULT vmx_emul_itr_d(VCPU *vcpu, INST64 inst)
        return IA64_FAULT;
     }
     if (unimplemented_gva(vcpu, ifa)) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
    }
@@ -703,9 +688,6 @@ static IA64FAULT vmx_emul_itr_i(VCPU *vcpu, INST64 inst)
        return IA64_FAULT;
     }
     if (unimplemented_gva(vcpu, ifa)) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
     }
@@ -764,9 +746,6 @@ static IA64FAULT itc_fault_check(VCPU *vcpu, INST64 inst,
     }
 #ifdef  VMAL_NO_FAULT_CHECK
     if (unimplemented_gva(vcpu,ifa) ) {
-        isr.val = set_isr_ei_ni(vcpu);
-        isr.code = IA64_RESERVED_REG_FAULT;
-        vcpu_set_isr(vcpu, isr.val);
         unimpl_daddr(vcpu);
         return IA64_FAULT;
     }
index 46e96b4d915d10648e2458ebb410911687192d2e..351b6c7a9effb27af648c470203eb9d64697c887 100644 (file)
@@ -582,6 +582,11 @@ privilege_op (VCPU *vcpu)
 static inline void
 unimpl_daddr (VCPU *vcpu)
 {
+       ISR isr;
+
+       isr.val = set_isr_ei_ni(vcpu);
+       isr.code = IA64_UNIMPL_DADDR_FAULT;
+       vcpu_set_isr(vcpu, isr.val);
        _general_exception(vcpu);
 }
 
@@ -695,4 +700,21 @@ data_access_rights(VCPU *vcpu, u64 vadr)
        set_ifa_itir_iha(vcpu, vadr, 1, 1, 0);
        inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR);
 }
+
+/*
+ * Unimplement Instruction Address Trap
+ *  @ Lower-Privilege Transfer Trap Vector
+ * Refer to SDM Vol2 Table 5-6 & 8-1
+ */
+static inline void
+unimpl_iaddr_trap (VCPU *vcpu, u64 vadr)
+{
+       ISR isr;
+
+       isr.val = set_isr_ei_ni(vcpu);
+       isr.code = IA64_UNIMPL_IADDR_TRAP;
+       vcpu_set_isr(vcpu, isr.val);
+       vcpu_set_ifa(vcpu, vadr);
+       inject_guest_interruption(vcpu, IA64_LOWERPRIV_TRANSFER_TRAP_VECTOR);
+}
 #endif